package com.sky.aspect;


import com.sky.anno.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import com.sky.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;


import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 自动填充切面类
 */
@Aspect
@Slf4j
@Component
public class AutoFillAspect {
    @Before(" @annotation(com.sky.anno.AutoFill)")
    public void AutoFill(JoinPoint joinPoint) {
        log.info("公共字段自动填充");
        //获得方法上的注解
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //获得方法签名对象
        Method method = methodSignature.getMethod();

        //获取当前目标方法的参数
        Object[] args = joinPoint.getArgs();
        log.info(Arrays.toString(args));
        //实体对象
        if (args == null || args.length == 0 || args[0] == null) {
            log.warn("方法参数为空或第一个参数为空");
            return;
        }
        Object enity = args[0];
        log.info(enity.toString());
        //获得注解中的操作类型
        AutoFill annotation = method.getAnnotation(AutoFill.class);

        OperationType operationType = annotation.value();
        log.info("操作类型: " + operationType);

        //准备赋值的数据
        try {
            if (operationType.equals(OperationType.INSERT)) {
                Method setCreateTime = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setCreateUser = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                setCreateTime.invoke(enity, LocalDateTime.now());
                setCreateUser.invoke(enity, BaseContext.getCurrentId());
                setUpdateTime.invoke(enity, LocalDateTime.now());
                setUpdateUser.invoke(enity, BaseContext.getCurrentId());
            } else {
                Method setUpdateTime = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = enity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                setUpdateTime.invoke(enity, LocalDateTime.now());
                setUpdateUser.invoke(enity, BaseContext.getCurrentId());
            }
        } catch (Exception e) {
            throw new BaseException(MessageConstant.AUTO_FILL_FALIURE);
        }
    }
}
